package com.tplhk.drool.controller;

import com.google.common.collect.Lists;
import com.tplhk.drool.entity.*;
import com.tplhk.drool.service.ClaimService;
import com.tplhk.drool.service.IRuleVoResult;
import com.tplhk.drool.util.KieHelpUtil;
import com.tplhk.drool.vo.ResponseData;
import lombok.extern.slf4j.Slf4j;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@Slf4j
@RequestMapping(value = "/excel")
@RestController
public class ExcelRuleController {

    @Autowired
    ClaimService claimService;

    /**
     * 导入的规则 action 返回是简单的字符串
     *
     * @return
     * @throws FileNotFoundException
     */
    @PostMapping(value = "/import")
    public ResponseData importRules() throws FileNotFoundException {
        String realPath = "d:\\testRule.xls";//指定决策表xls文件的磁盘路径
        File file = new File(realPath);
        InputStream is = new FileInputStream(file);
        SpreadsheetCompiler compiler = new SpreadsheetCompiler();
        String drl = compiler.compile(is, InputType.XLS);
        System.out.println(drl);


        KieFileSystem kfs = KieHelpUtil.kieHelper.kfs;
        kfs.delete("src/main/resources/" + "testRule.drl");
        log.info("Drools DRL was deleted sucessfully " + "testRule.drl");
        kfs.write("src/main/resources/" + "testRule.drl", drl);
        log.info("Drools DRL was created sucessfully " + "testRule.drl");

        return new ResponseData("导入成功");
    }

    @PostMapping(value = "/test")
    public ResponseData<List> test(@RequestBody PersonInfoEntity personInfoEntity) {
        KieSession session = KieHelpUtil.kieHelper.build().newKieSession();
        personInfoEntity.setSex(personInfoEntity.getSex());
        personInfoEntity.setAge(personInfoEntity.getAge());
        personInfoEntity.setSalary(personInfoEntity.getSalary());
        List<String> list = new ArrayList<>();
        session.setGlobal("listRules", list);
        session.insert(personInfoEntity);
        // 下面是指分组，只对这个组的所有规则判断
        session.getAgenda().getAgendaGroup("sign").setFocus();
        session.fireAllRules();
        for (String s : list) {
            System.out.println(s);
        }
        session.dispose();
        return new ResponseData(list);
    }


    /**
     * 导入的规则 action 返回是对象,注意 excel 有 function 用法
     *
     * @return
     * @throws FileNotFoundException
     */
    @PostMapping(value = "/import2")
    public ResponseData importRules2() throws FileNotFoundException {
        String realPath = "d:\\testRule2.xls";//指定决策表xls文件的磁盘路径
        File file = new File(realPath);
        InputStream is = new FileInputStream(file);
        SpreadsheetCompiler compiler = new SpreadsheetCompiler();
        String drl = compiler.compile(is, InputType.XLS);
        System.out.println(drl);

        KieFileSystem kfs = KieHelpUtil.kieHelper.kfs;
        kfs.delete("src/main/resources/" + "testRule2.drl");
        log.info("Drools DRL was deleted sucessfully " + "testRule2.drl");
        kfs.write("src/main/resources/" + "testRule2.drl", drl);
        log.info("Drools DRL was created sucessfully " + "testRule2.drl");

        return new ResponseData("导入成功");
    }

    @PostMapping(value = "/test2")
    public ResponseData<List> test2(@RequestBody PersonInfoEntity personInfoEntity) {
        KieSession session = KieHelpUtil.kieHelper.build().newKieSession();
        personInfoEntity.setSex(personInfoEntity.getSex());
        personInfoEntity.setAge(personInfoEntity.getAge());
        personInfoEntity.setSalary(personInfoEntity.getSalary());
        List<RuleVoResult> list = new ArrayList<>();
        session.setGlobal("listRules2", list);
        session.insert(personInfoEntity);
        session.fireAllRules();
        for (RuleVoResult s : list) {
            System.out.println(s.toString());
        }
        session.dispose();
        return new ResponseData(list);
    }


    /**
     * 导入的规则 action 返回是对象. 业务 demo.
     *
     * @return
     * @throws FileNotFoundException
     */
    @PostMapping(value = "/import3")
    public ResponseData importRules3() throws FileNotFoundException {
        String realPath = "d:\\testRule3.xls";//指定决策表xls文件的磁盘路径
        File file = new File(realPath);
        InputStream is = new FileInputStream(file);
        SpreadsheetCompiler compiler = new SpreadsheetCompiler();
        String drl = compiler.compile(is, InputType.XLS);
        System.out.println(drl);

        KieFileSystem kfs = KieHelpUtil.kieHelper.kfs;
        kfs.delete("src/main/resources/" + "testRule3.drl");
        log.info("Drools DRL was deleted sucessfully " + "testRule3.drl");
        kfs.write("src/main/resources/" + "testRule3.drl", drl);
        log.info("Drools DRL was created sucessfully " + "testRule3.drl");

        return new ResponseData("导入成功");
    }

    /**
     * 返回模型 RuleVo2Result ： 对应 excel 所有字段
     *
     * @param claimQueryVo
     * @return
     */
    @PostMapping(value = "/test3")
    public ResponseData<List> test3(@RequestBody ClaimQueryVo claimQueryVo) {
        KieSession session = KieHelpUtil.kieHelper.build().newKieSession();
        PersonInfoEntity personInfoEntity = new PersonInfoEntity();
        BeanUtils.copyProperties(claimQueryVo, personInfoEntity);
        IRuleVoResult ruleVo2Result = new RuleVo2Result(claimQueryVo, 0);
        session.setGlobal("ruleResult", ruleVo2Result);
        FactHandle insert = session.insert(personInfoEntity);
        session.fireAllRules();
        session.dispose();
        // 需要WorkingMemory调用retract方法将其从内存中清除掉，
        // 不然，即使走完了规则变成了垃圾对象，也无法被垃圾回收器回收
        session.delete(insert);
        /**
         * 对于 money 需要查 excel.salary 的处理
         */
        RuleBase moneyRuleBase = claimService.getBaseByField("salary", claimQueryVo.getMoney());

        ClaimResult claimResult = new ClaimResult();
        BeanUtils.copyProperties(ruleVo2Result, claimResult);
        BeanUtils.copyProperties(moneyRuleBase, claimResult.getMoney());

        return new ResponseData(claimResult);
    }


    /**
     * 与 test3 相同，只不过使用自下定义返回模型 RuleVo3Result. 如果只返回指定的字段或新增一些字段（但校验的规则仍在 excel ),需要用这种方式.
     *
     * @return
     * @throws FileNotFoundException
     */
    @PostMapping(value = "/test4")
    public ResponseData<List> test4(@RequestBody ClaimQueryVo claimQueryVo) {
        KieSession session = KieHelpUtil.kieHelper.build().newKieSession();
        PersonInfoEntity personInfoEntity = new PersonInfoEntity();
        BeanUtils.copyProperties(claimQueryVo, personInfoEntity);
        RuleVo3Result ruleVo3Result = new RuleVo3Result(claimQueryVo, 1);
        session.setGlobal("ruleResult", ruleVo3Result);
        session.insert(personInfoEntity);
        session.fireAllRules();
        session.dispose();


        /**
         * 对于 money 需要查 excel.salary 的处理
         */
        RuleBase moneyBase = claimService.getBaseByField("salary", claimQueryVo.getMoney(), -1);

        /**
         * 对于 list 需要查 excel.salary 的处理
         */
        List<Object> moneyList = Lists.newArrayList(new Double(100d), new Double(1000000), new Double(20000000d));
        List<RuleBase> moneyRuleBaseList = claimService.getBaseByField("salary", moneyList, -1);
        Long maxSalary = moneyRuleBaseList.stream().mapToLong(RuleBase::getScore).max().getAsLong();
        RuleBase salaryBase = moneyRuleBaseList.stream().max(Comparator.comparing(RuleBase::getScore)).get();

        BeanUtils.copyProperties(salaryBase, ruleVo3Result.getSalary());
        BeanUtils.copyProperties(moneyBase, ruleVo3Result.getMoney());

        return new ResponseData(ruleVo3Result);
    }

}
